package handler

import (
	"app-box/api_error"
	"app-box/config"
	"app-box/middleware"
	"app-box/models"
	"app-box/service"
	"app-box/tools"
	"regexp"
	"time"

	"github.com/gin-gonic/gin"
	mgin "github.com/ulule/limiter/v3/drivers/middleware/gin"
)

// Login User Login
type UserHandler struct {
}

// InitRoute 初始化路由
func (h UserHandler) InitRoute(router gin.IRouter) {
	limitDuration := time.Minute * 10
	limitFunc := middleware.Limit(10, limitDuration, mgin.WithLimitReachedHandler(H(OnLimitReachedHandler(limitDuration))))

	router.POST("/login", limitFunc, H(h.login))
	router.POST("/login/cas", limitFunc, H(h.CASLogin))
	router.POST("/register", limitFunc, H(h.register))
	router.POST("/refreshToken", H(h.refreshToken))

	var user = router.Group("user").Use(middleware.RequireLogin(models.UserTypeAll))
	{
		user.GET("/getInfo", H(h.getInfo))
		user.POST("/updateInfo", H(h.updateInfo))
	}

}

// Login User Login
func (h UserHandler) login(ctx Context) {
	var form struct {
		UserName string               `binding:"required"`
		Password string               `binding:"required"`
		Platform models.LoginPlatform `binding:"oneof=i a w"`
	}
	ctx.ShouldBindOrPanic(&form)
	var service = service.NewUserService()
	token := service.Login(form.UserName, form.Password, form.Platform)
	ctx.Response(token)
}

// Login User Login
func (h UserHandler) register(ctx Context) {
	var form struct {
		UserName string `binding:"required"`
		Password string `binding:"required"`
	}

	ctx.ShouldBindOrPanic(&form)
	ismatch, err := regexp.MatchString(config.User.PasswordRule, form.Password)
	if err != nil {
		panic(err)
	}
	if !ismatch { // 密码不符合规范
		panic(api_error.PasswordRuleError())
	}
	var service = service.NewUserService()
	service.Register(form.UserName, form.Password)
	ctx.ResponseSuccess()
}

// CAS 单点登录
func (h UserHandler) CASLogin(ctx Context) {
	var form struct {
		Ticket   string               `binding:"required"`
		Service  string               `binding:"required"`
		Platform models.LoginPlatform `binding:"oneof=i a w"`
	}
	ctx.ShouldBindOrPanic(&form)

	var service = service.NewUserService()
	token := service.CASLogin(form.Ticket, form.Service, form.Platform)
	ctx.Response(token)
}

func (h UserHandler) refreshToken(ctx Context) {
	var form struct {
		RefreshToken string `binding:"required"`
	}
	ctx.ShouldBindOrPanic(&form)
	var refreshToken models.Token
	if err := tools.NewTokenTool(config.Server.TokenSalt).FormatToken(form.RefreshToken, &refreshToken); err != nil {
		panic(err)
	}
	var service = service.NewUserService()
	token := service.RefreshToken(refreshToken)
	ctx.Response(token)
}

func (h UserHandler) getInfo(ctx Context) {
	ctx.Response(map[string]interface{}{
		"xx": 123,
	})
}

func (h UserHandler) updateInfo(ctx Context) {
	ctx.Response(map[string]interface{}{
		"xx": 123,
	})
}
